package com.scalar.chiptrack.operations.process;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.operations.dataentry.LotDetails;
import com.scalar.chiptrack.operations.process.dao.NewProductDAO;
import com.scalar.chiptrack.users.notification.dao.NotificationDAO;
import com.scalar.chiptrack.commons.Constants;
import com.scalar.chiptrack.utils.ConfigManager;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.utils.Mailer;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.dao.NewAdaptorDAO;
import com.scalar.ScalarException;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * User: Sujan
 * Date: Feb 7, 2008
 * Time: 6:05:40 PM
 */
public class ProductChangeMailingJob extends JobHandler
{
    private Logger m_parserLogger     = null;

    public ProductChangeMailingJob() throws Exception
    {
        try
        {
            m_parserLogger = new Logger(  "./logs", "productChangeMailingJob", "Parser", "debug", 1024 * 1000, 1 );
        }
        catch( Exception e )
        {
            e.printStackTrace();
        }
    }
    // To be implemented by sub classes
    public void execute() throws Exception
    {
        printHeader();
        StringBuffer alertMailMsg = new StringBuffer();
        try
        {
            ArrayList productChangeList = NewProductDAO.getProductChangeList( null );
            if ( productChangeList != null && productChangeList.size() > 0 )
            {
                alertMailMsg.append ( "<HTML><HEAD><TITLE>Product Loader Porting Status</TITLE></HEAD>" );
                alertMailMsg.append ( "<BODY><TABLE STYLE='FONT-SIZE: 8PT; COLOR: BLACK; FONT-FAMILY: VERDANA' BORDERCOLOR='#FFFFFF' CELLSPACING='1' CELLPADDING='3' WIDTH='80%' BORDER=0 ALIGN='CENTER'>" );
                alertMailMsg.append ( "<TR BGCOLOR='#CCCCFF'><TD COLSPAN='6' ALIGN='CENTER'><B>PRODUCT CHANGE NOTIFICATION REPORT</B></TD></TR>" );
                alertMailMsg.append ( "<TR BGCOLOR='#D3D3D6' ALIGN='CENTER'>" );
                alertMailMsg.append ( "<TD><B>PART NUMBER</B></TD><TD><B>PROCESS TYPE</B></TD><TD><B>STATUS</B></TD><TD><B>DESCRIPTION</B></TD></TR>" );
                ArrayList notifiableList = getNotifiableList ( productChangeList );
                int listSize = ( notifiableList != null ) ? notifiableList.size() : 0;
                for ( int i = 0; i < listSize; i++ )
                {
                    ProductChange notifiableProduct = ( ProductChange )notifiableList.get( i );
                    alertMailMsg.append ( "<TR BGCOLOR='#E6E6E6' ALIGN='CENTER'>" );
                    alertMailMsg.append ( "<TD>" ).append ( notifiableProduct.getPartNumber() == null ? "" : notifiableProduct.getPartNumber() ).append ( "</TD>" );
                    alertMailMsg.append ( "<TD>" ).append ( notifiableProduct.getPsType() == null ? "" : notifiableProduct.getPsType() ).append ( "</TD>" );
                    alertMailMsg.append ( "<TD>" ).append ( notifiableProduct.getStatus() ).append ( "</TD>" );
                    alertMailMsg.append ( "<TD ALIGN='LEFT'>" ).append ( notifiableProduct.getDescription() ).append ( "</TD>" );
                    alertMailMsg.append ( "</TR>" );

                }
                alertMailMsg.append ( "</TABLE></BODY>").append( "\n</HTML>" );
                String[] mailAttachments = null;
                String[] emailArray = NotificationDAO.loadEmailsByNSType ( null, null, Constants.PRODUCT_CHANGE_NOTIFICATION );

                String from = ConfigManager.getSysAdminEmail();
                String to = StringUtils.concatStrings( emailArray, Mailer.EMAIL_SEPARATOR );
				//System.out.println("To  :  " + to );

                String subject = "Product Change Notification";
                if ( to != null && to.trim().length() > 0 )
                {
                    Mailer.send( from, to, null, null, subject, alertMailMsg.toString(), mailAttachments, Mailer.CONTENT_TYPE_HTML, false );
                    log ( "Product Change Notification mail sent successfully" );
                    System.out.println ( "Product Change Notification mail sent successfully" );
                    try
                    {
                        NewProductDAO.updateAlertStatusforProductChange (null);
                        log ( "Product Change Notification alert status updated successfully" );
                        System.out.println ( "Product Change Notification alert status updated successfully" );
                    }
                    catch ( ScalarException e )
                    {
                        log ( "ERROR!!! Could not update Product Change Notification alert status", e );
                        System.out.println ( "ERROR!!! Could not update Product Change Notification alert status:" + e.getMessage() );
                    }
                }
                else
                {
                    log ( "WARNING!!! could not found recipient emails" );
                    System.out.println ( "WARNING!!! could not found recipient emails" );
                }
            }
            else
            {
                log ( "WARNING!!! Could not found Product Change Info" );
                System.out.println ( "WARNING!!! Could not found Product Change Info" );
            }
        }
        catch( Exception e)
        {
            log ( "ERROR!!! Could not send Product Change Notification mail", e );
            System.out.println ( "ERROR!!! Could not send Product Change Notification mail:" + e.getMessage() );
            throw new ScalarException ( "Could not Send Product Change Notification", e );
        }

		sendYieldNotifications();

        sendLotChangeNotifications();

        sendBomInventoryReOrderNotifications();
    }

	private void sendYieldNotifications() throws ScalarException
	{
        StringBuffer alertMailMsg = new StringBuffer();
        double yield = 0.0;
        try
        {
            ArrayList yieldNotificationList = NewProductDAO.getYieldNotificationList();
            if ( yieldNotificationList != null && yieldNotificationList.size() > 0 )
            {
                alertMailMsg.append ( "<HTML><HEAD><TITLE>Shipped Lot Yield Information</TITLE></HEAD>" );
                alertMailMsg.append ( "<BODY><TABLE STYLE='FONT-SIZE: 8PT; COLOR: BLACK; FONT-FAMILY: VERDANA' BORDERCOLOR='#FFFFFF' CELLSPACING='1' CELLPADDING='3' WIDTH='80%' BORDER=0 ALIGN='CENTER'>" );
                alertMailMsg.append ( "<TR BGCOLOR='#CCCCFF'><TD COLSPAN='9' ALIGN='CENTER'><B>Lot Yield NOTIFICATION REPORT</B></TD></TR>" );
                alertMailMsg.append ( "<TR BGCOLOR='#D3D3D6' ALIGN='CENTER'>" );
                alertMailMsg.append ( "<TD><B>PART NUMBER</B></TD><TD><B>Lot Number</B></TD><TD><B>Fab Lot Number</B></TD><TD><B>Vendor</B></TD><TD><B>Process</B></TD><TD><B>Ship Date</B></TD><TD><B>Qty In</B></TD><TD><B>Qty Out</B></TD><TD><B>Yield</B></TD></TR>" );

                int listSize = ( yieldNotificationList != null ) ? yieldNotificationList.size() : 0;
                for ( int i = 0; i < listSize; i++ )
                {
                	LotDetails lotDetail = ( LotDetails )yieldNotificationList.get( i );
                    alertMailMsg.append ( "<TR BGCOLOR='#E6E6E6' ALIGN='CENTER'>" );
                    alertMailMsg.append ( "<TD>" ).append ( lotDetail.getPartNumber() == null ? "" : lotDetail.getPartNumber() ).append ( "</TD>" );
                    alertMailMsg.append ( "<TD>" ).append ( lotDetail.getLotNumber() == null ? "" : lotDetail.getLotNumber() ).append ( "</TD>" );
                    alertMailMsg.append ( "<TD>" ).append ( lotDetail.getFabLotNumber() == null ? "" : lotDetail.getFabLotNumber() ).append ( "</TD>" );
                    
                    //System.out.println("Vendor Name : " + lotDetail.getVendorName());
                    alertMailMsg.append ( "<TD>" ).append ( lotDetail.getVendorName() ).append ( "</TD>" );
                    alertMailMsg.append ( "<TD>" ).append ( lotDetail.getProcessType() ).append ( "</TD>" );
                    alertMailMsg.append ( "<TD>" ).append ( lotDetail.getShipDate() ).append ( "</TD>" );
                    alertMailMsg.append ( "<TD>" ).append ( lotDetail.getDieQtyIn() ).append ( "</TD>" );
                    alertMailMsg.append ( "<TD>" ).append ( lotDetail.getShipDieQty() ).append ( "</TD>" );
                    
                    try
					{
                    	yield = (Double.parseDouble( lotDetail.getShipDieQty())/Double.parseDouble( lotDetail.getDieQtyIn() ) )*100;
					}
                    catch(Exception e)
					{
                    	yield = 100.00;
                    	e.getStackTrace();
					}
                    
                    alertMailMsg.append ( "<TD>" ).append(  StringUtils.formatAmount( yield, "###.##" ) ).append ( "</TD>" );
                    alertMailMsg.append ( "</TR>" );

                }
                
                //System.out.println( alertMailMsg.toString() );
                alertMailMsg.append ( "</TABLE></BODY>").append( "\n</HTML>" );
                String[] mailAttachments = null;
                String[] emailArray = NotificationDAO.loadEmailsByNSType ( null, null, Constants.YIELD_NOTIFICATION );

                String from = ConfigManager.getSysAdminEmail();
                String to = StringUtils.concatStrings( emailArray, Mailer.EMAIL_SEPARATOR );
                String subject = "Lot Yield Notification";
                
                if ( to != null && to.trim().length() > 0 )
                {
                    Mailer.send( from, to, null, null, subject, alertMailMsg.toString(), mailAttachments, Mailer.CONTENT_TYPE_HTML, false );
                    log ( "Lot Yield Notification mail sent successfully" );
                    System.out.println ( "Lot Yield Notification mail sent successfully" );
                    try
                    {
                    	NewAdaptorDAO.updateUserNotifiedDetails( Constants.YIELD_NOTIFICATION );
                        log ( "Lot Yield Notification alert status updated successfully" );
                        System.out.println ( "Lot Yield Notification alert status updated successfully" );
                    }
                    catch ( ScalarException e )
                    {
                        log ( "ERROR!!! Could not update Lot Yield Notification alert status", e );
                        System.out.println ( "ERROR!!! Could not update Lot Yield Notification alert status:" + e.getMessage() );
                    }
                }
                else
                {
                    log ( "WARNING!!! could not found recipient emails" );
                    System.out.println ( "WARNING!!! could not found recipient emails" );
                }
            }
            else
            {
                log ( "WARNING!!! Could not found Lot Yield Notification Info" );
                System.out.println ( "WARNING!!! Could not found Lot Yield Notification Info" );
            }
        }
        catch( Exception e)
        {
            log ( "ERROR!!! Could not send Lot Yield Notification mail", e );
            System.out.println ( "ERROR!!! Could not send Lot Yield Notification mail:" + e.getMessage() );
            throw new ScalarException ( "Could not Send Lot Yield Notification", e );
        }
	}
    
	private void sendLotChangeNotifications() throws ScalarException
	{
        StringBuffer alertMailMsg = new StringBuffer();

        try
        {
            ArrayList<ProductChange> lotChangeList = NewProductDAO.getLotChangeList( null );
            if ( lotChangeList != null && lotChangeList.size() > 0 )
            {
                alertMailMsg.append ( "<HTML><HEAD><TITLE>Lot Change Information</TITLE></HEAD>" );
                alertMailMsg.append ( "<BODY><TABLE STYLE='FONT-SIZE: 8PT; COLOR: BLACK; FONT-FAMILY: VERDANA' BORDERCOLOR='#FFFFFF' CELLSPACING='1' CELLPADDING='3' WIDTH='80%' BORDER=0 ALIGN='CENTER'>" );
                alertMailMsg.append ( "<TR BGCOLOR='#CCCCFF'><TD COLSPAN='5' ALIGN='CENTER'><B>LOT CHANGE NOTIFICATION REPORT</B></TD></TR>" );
                alertMailMsg.append ( "<TR BGCOLOR='#D3D3D6' ALIGN='CENTER'>" );
                alertMailMsg.append ( "<TD><B>Lot Number</B></TD><TD><B>Fab Lot Number</B></TD><TD><B>Vendor</B></TD><TD><B>Process</B></TD>" +
                        "<TD><B>Description</B></TD></TR>" );

                int listSize = ( lotChangeList != null ) ? lotChangeList.size() : 0;
                for ( int i = 0; i < listSize; i++ )
                {
                    String description = null;
                	ProductChange changelotDetail = lotChangeList.get( i );
                    alertMailMsg.append ( "<TR BGCOLOR='#E6E6E6' ALIGN='CENTER'>" );
                    alertMailMsg.append ( "<TD>" ).append ( changelotDetail.getLotNumber() == null ? "" : changelotDetail.getLotNumber() ).append ( "</TD>" );
                    alertMailMsg.append ( "<TD>" ).append ( changelotDetail.getFabLotNumber() == null ? "" : changelotDetail.getFabLotNumber() ).append ( "</TD>" );
                    alertMailMsg.append ( "<TD>" ).append ( changelotDetail.getVendorName() ).append ( "</TD>" );
                    alertMailMsg.append ( "<TD>" ).append ( changelotDetail.getPsType() ).append ( "</TD>" );
                    if ("CHANGED".equalsIgnoreCase(changelotDetail.getStatus() ) )
                    {
                         description = "<B>" + changelotDetail.getFieldName() + "</B> changed from  <B>" + changelotDetail.getOldValue() + "</B> To <B>" + changelotDetail.getNewValue() + "</B>";
                    }
                    alertMailMsg.append ( "<TD>" ).append ( description ).append ( "</TD>" );

                    alertMailMsg.append ( "</TR>" );

                }

                //System.out.println( alertMailMsg.toString() );
                alertMailMsg.append ( "</TABLE></BODY>").append( "\n</HTML>" );
                String[] mailAttachments = null;
                String[] emailArray = NotificationDAO.loadEmailsByNSType ( null, null, Constants.LOT_CHANGE_NOTIFICATION );

                String from = ConfigManager.getSysAdminEmail();
                String to = StringUtils.concatStrings( emailArray, Mailer.EMAIL_SEPARATOR );
                String subject = "Lot Change Notification";

                if ( to != null && to.trim().length() > 0 )
                {
                    Mailer.send( from, to, null, null, subject, alertMailMsg.toString(), mailAttachments, Mailer.CONTENT_TYPE_HTML, false );
                    log ( "Lot Change Notification mail sent successfully" );
                    System.out.println ( "Lot Change Notification mail sent successfully" );
                    try
                    {
                    	NewProductDAO.updateAlertStatusforLotChange( null);
                        log ( "Lot Change Notification alert status updated successfully" );
                        System.out.println ( "Lot Change Notification alert status updated successfully" );
                    }
                    catch ( ScalarException e )
                    {
                        log ( "ERROR!!! Could not update Lot Change Notification alert status", e );
                        System.out.println ( "ERROR!!! Could not update Lot Change Notification alert status:" + e.getMessage() );
                    }
                }
                else
                {
                    log ( "WARNING!!! could not found recipient emails" );
                    System.out.println ( "WARNING!!! could not found recipient emails" );
                }
            }
            else
            {
                log ( "WARNING!!! Could not found Lot Change Notification Info" );
                System.out.println ( "WARNING!!! Could not found Lot Change Notification Info" );
            }
        }
        catch( Exception e)
        {
            log ( "ERROR!!! Could not send Lot Change Notification mail", e );
            System.out.println ( "ERROR!!! Could not send Lot Change Notification mail:" + e.getMessage() );
            throw new ScalarException ( "Could not Send Lot Change Notification", e );
        }
    }
    private void sendBomInventoryReOrderNotifications() throws ScalarException
	{
        StringBuffer alertMailMsg = new StringBuffer();

        try
        {
            ArrayList<ProductChange> partList = NewProductDAO.getBomInvReOrderPartList( null );
            if ( partList != null && partList.size() > 0 )
            {
                alertMailMsg.append ( "<HTML><HEAD><TITLE>BOM Inventory ReOrder Information</TITLE></HEAD>" );
                alertMailMsg.append ( "<BODY><TABLE STYLE='FONT-SIZE: 8PT; COLOR: BLACK; FONT-FAMILY: VERDANA' BORDERCOLOR='#FFFFFF' CELLSPACING='1' CELLPADDING='3' WIDTH='80%' BORDER=0 ALIGN='CENTER'>" );
                alertMailMsg.append ( "<TR BGCOLOR='#CCCCFF'><TD COLSPAN='4' ALIGN='CENTER'><B>BOM Inventory Reorder NOTIFICATION</B></TD></TR>" );
                alertMailMsg.append ( "<TR BGCOLOR='#D3D3D6' ALIGN='CENTER'>" );
                alertMailMsg.append ( "<TD><B>Part Number</B></TD><TD><B>Reorder Level Qty</B></TD><TD><B>Available Qty</B></TD><TD><B>Description</B></TD></TR>" );

                int listSize = ( partList != null ) ? partList.size() : 0;
                for ( int i = 0; i < listSize; i++ )
                {
                    String description = null;
                	ProductChange changelotDetail = partList.get( i );
                    alertMailMsg.append ( "<TR BGCOLOR='#E6E6E6' ALIGN='CENTER'>" );
                    alertMailMsg.append ( "<TD>" ).append ( changelotDetail.getPartNumber() == null ? "" : changelotDetail.getPartNumber() ).append ( "</TD>" );
                    alertMailMsg.append ( "<TD>" ).append ( changelotDetail.getReorderLevelQty() == null ? "" : changelotDetail.getReorderLevelQty() ).append ( "</TD>" );
                    alertMailMsg.append ( "<TD>" ).append ( changelotDetail.getQtyIn()  == null ? "" : changelotDetail.getQtyIn() ).append ( "</TD>" );
                    description = "Available BOM Inventory <B>(" + changelotDetail.getQtyIn() + ")</B> is less than Reorder Level Qty <B>(" + changelotDetail.getReorderLevelQty() + " )</B>";

                    alertMailMsg.append ( "<TD>" ).append ( description ).append ( "</TD>" );

                    alertMailMsg.append ( "</TR>" );

                }

                //System.out.println( alertMailMsg.toString() );
                alertMailMsg.append ( "</TABLE></BODY>").append( "\n</HTML>" );
                String[] mailAttachments = null;
                String[] emailArray = NotificationDAO.loadEmailsByNSType ( null, null, Constants.BOM_REORDER_NOTIFICATION );

                String from = ConfigManager.getSysAdminEmail();
                String to = StringUtils.concatStrings( emailArray, Mailer.EMAIL_SEPARATOR );
                String subject = "BOM Invnetory Reorder Notification";
                
                if ( to != null && to.trim().length() > 0 )
                {
                    Mailer.send( from, to, null, null, subject, alertMailMsg.toString(), mailAttachments, Mailer.CONTENT_TYPE_HTML, false );
                    log ( "BOM Invnetory Reorder Notification mail sent successfully" );
                    System.out.println ( "BOM Invnetory Reorder Notification mail sent successfully" );

                }
                else
                {
                    log ( "WARNING!!! could not found recipient emails" );
                    System.out.println ( "WARNING!!! could not found recipient emails" );
                }
            }
            else
            {
                log ( "WARNING!!! Could not found BOM Invnetory Reorder Notification Info" );
                System.out.println ( "WARNING!!! Could not found BOM Invnetory Reorder Notification Info" );
            }
        }
        catch( Exception e)
        {
            log ( "ERROR!!! Could not send BOM Invnetory Reorder Notification mail", e );
            System.out.println ( "ERROR!!! Could not send BOM Invnetory Reorder Notification mail:" + e.getMessage() );
            throw new ScalarException ( "Could not Send BOM Invnetory Reorder Notification", e );
        }
    }
	private ArrayList getNotifiableList ( ArrayList productChangeList )
    {
        HashMap notifiableMap = new HashMap();
        ProductChange productChange;
        ProductChange notifiableProduct;
        int listSize = ( productChangeList != null ) ? productChangeList.size() : 0;

        for ( int i = 0; i < listSize; i++ )
        {
            productChange = (ProductChange)productChangeList.get( i );
            if ( notifiableMap.containsKey( productChange.getProcessStepId()+"" ) )
            {
                notifiableProduct = ( ProductChange )notifiableMap.get( productChange.getProcessStepId()+"" );
            }
            else
            {
                notifiableProduct = new ProductChange();
                notifiableMap.put( productChange.getProcessStepId()+"", notifiableProduct );
                notifiableProduct.setProcessStepId( productChange.getProcessStepId() );
                notifiableProduct.setPartNumber( productChange.getPartNumber() );
                notifiableProduct.setPsType( productChange.getPsType() );
            }
            notifiableProduct.setStatus( productChange.getStatus() );
            String description = notifiableProduct.getDescription();
            if ( description == null || description.trim().length() == 0 )
            {
                description = "";
            }
            else
            {
                description = description + "<BR>";
            }
            if ( "NEW".equalsIgnoreCase( productChange.getStatus() ) )
            {
                description = description + "<B>" + productChange.getFieldName() + ": </B>" + productChange.getNewValue();
            }
            else if ( "DELETED".equalsIgnoreCase( productChange.getStatus() ) )
            {
                description = description + "<B>" + productChange.getFieldName() + ": </B>" + productChange.getOldValue();
            }
            else
            {
                description = description + "<B>" + productChange.getFieldName() + "</B> changed from  <B>" + productChange.getOldValue() + "</B> To <B>" + productChange.getNewValue() + "</B>";
            }
            notifiableProduct.setDescription( description );
        }
        return new ArrayList( notifiableMap.values() );
    }
    public static void main( String[] args ) throws Exception
    {
        new ProductChangeMailingJob().execute();
    }
    private void printHeader()
    {
        String info = "\n\n+----------- Running Product Change Notification Job on " + new java.util.Date( System.currentTimeMillis() ) + " -------------+\n" +
                 "\n+---------------------------------------------------------------+\n" +
                 "+                                                                \n" +
                 "+            Product Change Notification  - Beta          \n" +
                 "+                                                                \n" +
                 "+    Copy Right (C) 2008 - ScalarSoft Inc., All rights reserved.  \n" +
                 "+                                                                \n" +
                 "+---------------------------------------------------------------+\n" ;
        System.out.println ( info );
        log( info );
    }
    private void log( String message )
    {
        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            m_parserLogger.logDebug( message + AdaptorConstants.LINE_SEPARATOR );
        }
        else
        {
            System.out.println( message );
        }
    }
    private void log(String message, Throwable e )
    {
        if (m_parserLogger != null)
        {
            synchronized (m_parserLogger)
            {
                m_parserLogger.logError(message + LINE_SEPARATOR, e );
            }
        }
        else
        {
            System.out.println(message);
            e.printStackTrace();
        }
    }
}
